#include "ty_pwm.h"
#include "peripheral.h"

/*********************************************************************
 * CONSTANT
 */
#define COUNT_FREQ_MAX              32000000
#define PERIOD_COUNT                100

/*********************************************************************
 * STRUCT
 */

/*********************************************************************
 * VARIABLE
 */
static tim_config_t pwm_cfg;

/*********************************************************************
 * FUNCTION
 */
/*********************************************************
FN: 
*/
uint32_t ty_pwm_init(ty_pwm_t* p_pwm)
{
    uint32_t cnt_freq = p_pwm->freq * PERIOD_COUNT;
    if (cnt_freq > COUNT_FREQ_MAX)
    {
        TY_PRINTF("Error: frequency is too large.");
        return -1;
    }

    pwm_cfg.mode = TIM_PWM_MODE;
    pwm_cfg.config.pwm.count_freq = cnt_freq;
    pwm_cfg.config.pwm.period_count = PERIOD_COUNT;
    pwm_cfg.config.pwm.channel[0].enable = true;
    pwm_cfg.config.pwm.channel[0].config.pol = p_pwm->polarity;
    pwm_cfg.config.pwm.channel[0].config.pulse_count = p_pwm->duty;

    // Pinmux
    pinmux_config(p_pwm->pin, PINMUX_TIMER1_IO_0_CFG);

    // PWM Init
    tim_init();
    tim_config(HS_TIM1, &pwm_cfg);

    return 0;
}

/*********************************************************
FN: 
*/
uint32_t ty_pwm_start(ty_pwm_t* p_pwm)
{
    TY_PRINTF("pwm start");
    tim_stop(HS_TIM1);
    uint32_t cnt_freq = p_pwm->freq * PERIOD_COUNT;
    pwm_cfg.config.pwm.count_freq = cnt_freq;
    pwm_cfg.config.pwm.channel[0].config.pulse_count = p_pwm->duty;
    tim_config(HS_TIM1, &pwm_cfg);
    tim_start(HS_TIM1);
    return 0;
}

/*********************************************************
FN: 
*/
uint32_t ty_pwm_stop(ty_pwm_t* p_pwm)
{
    tim_stop(HS_TIM1);
    return 0;
}

/*********************************************************
FN: 
*/
uint32_t ty_pwm_control(ty_pwm_t* p_pwm, uint8_t cmd, void* arg)
{
    return 0;
}

/*********************************************************
FN: 
*/
uint32_t ty_pwm_uninit(ty_pwm_t* p_pwm)
{
    tim_stop(HS_TIM1);
    pinmux_config(p_pwm->pin, PINMUX_GPIO_MODE_CFG);
    pmu_pin_mode_set(BITMASK(p_pwm->pin), PMU_PIN_MODE_PU);
    return 0;
}
